<template>
  <template v-if="loaded">
    <ProForm
      ref="formRef"
      :model="formState"
      :items="items"
      :disabled="readonly"
      :onValuesChange="onValuesChange"
      :formColLayout="formColLayout()"
      :requiredMark="!readonly"
      class="pro-form-modal warn-form-modal"
      v-bind="formProps"
    >
    </ProForm>
    <FooterButtons
      :formState="formState"
      :formRef="formRef"
      v-model:readonly="readonly"
      :serviceApi="_updateWarnConfig"
      @refresh="refresh"
      :fastConfig="fastConfig"
    />
  </template>
</template>

<script setup lang="tsx">
import { computed, h, nextTick, ref, shallowRef, toRaw } from 'vue';
import { UploadOutlined } from '@ant-design/icons-vue';
import {
  Button,
  Modal,
  Space,
  TimeRangePicker,
  Tooltip,
  Upload,
  type UploadProps,
  message,
} from 'ant-design-vue';
import { ProForm, ProFormProps } from '@/components/ProForm';
import { ItemProps } from '@/components/ProForm/interface';
import {
  getWarnConfig_2,
  importCertGen,
  updateWarnConfig_2,
} from '@/api/device';
import FooterButtons from './FooterButtons.vue';

defineOptions({
  name: 'Warn',
});

interface Props {
  pageData: any;
  readonly?: any;
  fastConfig?: boolean;
}
const props = defineProps<Props>();
const loaded = ref(false);
const readonly = ref(props.readonly ?? true);
const formRef = shallowRef();
const formState = ref<Record<string, any>>({});
const column = 3;
const formColLayout = () => {
  const num = 24 / column;
  return { xs: num, sm: num, md: num, lg: num };
};
const formProps = computed<ProFormProps>(() => {
  return {
    labelCol: { span: 9 },
    wrapperCol: { span: 20 },
  };
});
const onValuesChange = (
  values: Record<string, any>,
  state: Record<string, any>,
) => {
  formState.value = {
    ...formState.value,
    ...state,
  };
};
const refresh = () => {
  loaded.value = false;
  nextTick(() => {
    loaded.value = true;
  });
};
const itemObj = (
  label: string,
  type: any,
  field: any,
  required: boolean = false,
  props?: any,
  layout?: any,
  rules: any = [],
): ItemProps => {
  return {
    label,
    type,
    field,
    props: {
      placeholder: `请${type == 'input' || type == 'number' ? '输入' : '选择'}${label}`,
      allowClear: false,
      ...props,
    },
    rules: [
      {
        required,
        message: `请${type == 'input' || type == 'number' ? '输入' : '选择'}${label}`,
        trigger: 'blur',
      },
      ...rules,
    ],
    ...layout,
  };
};
const itemRender = (title: string): ItemProps => {
  return {
    label: { title },
    type: 'input',
    field: 'h5',
    formItemRender() {
      return <h5 class='h5'>{title}</h5>;
    },
  };
};
const radioOptions = [
  { value: '0', label: '关闭' },
  { value: '1', label: '开启' },
];
const levelOption = [...Array(12)].map((_, i) => ({ value: i + 1 }));
const levelConfigList = [
  'warnNoneScope',
  'warnBlueScope',
  'warnYellowScope',
  'warnOrangeScope',
  'warnRedScope',
];
const warmProps = (color: string) => {
  return {
    options: levelOption,
    mode: 'multiple',
    showArrow: true,
    style: { '--alertLevel': color, color: '#0c0c0c' },
    onChange(value: any) {
      levelConfigList.forEach((key: any) => {
        let item = formRef.value.getFieldsValue()[key];
        if (value != toRaw(item)) {
          removeRepeat(item, value);
        } else {
          value.sort((a: any, b: any) => {
            return a - b;
          });
        }
      });
    },
    disabled: formState.value.isAutoSynWarnScope == 1,
  };
};
const warmRules = [
  {
    required: false,
    message: '所选等级必须连续，不可跳选',
    validator(rule: any, value: any, callback: any) {
      if (value) {
        for (let j = 1; j < value.length; j++) {
          if (value[j] != value[j - 1] + 1) {
            return Promise.reject('不连续');
          }
        }
      }
      return Promise.resolve();
    },
    trigger: ['blur', 'change'],
  },
];
const itemSelect = (
  label: string,
  field: any,
  required: boolean,
  color: string,
): [string, string, string, boolean, any, any, any] => {
  return [
    label,
    'select',
    field,
    required,
    warmProps(color),
    { labelCol: { span: 7 } },
    warmRules,
  ];
};
const itemNumber = (
  label: string,
  field: any,
): [string, string, string, boolean, any, any] => {
  return [
    label,
    'number',
    field,
    false,
    {
      min: 1,
      max: 12,
      step: 0.1,
      precision: 1,
      addonBefore: '>=',
    },
    { labelCol: { span: 6 } },
  ];
};
const itemCheckbox = (
  label: string,
  field: any,
): [string, string, string, boolean, any, any] => {
  return [
    label,
    'checkboxGroup',
    field,
    field == 'warnNoneResponseConfig' ? false : true,
    {
      options: field == 'warnNoneResponseConfig' ? warnNoneConfig : warnConfig,
    },
    {
      labelCol: { span: 4 },
      wrapperCol: { span: 24 },
      colProps: {
        span: 12,
      },
      class: field == 'warnNoneResponseConfig' ? 'warn-none' : undefined,
    },
  ];
};
const warnNoneConfig = [
  { label: '屏显', value: '屏显' },
  { label: '警报', value: '警报', disabled: true },
  { label: '提示灯', value: '提示灯' },
  { label: '录像', value: '录像', disabled: true },
  { label: '采集', value: '采集', disabled: true },
  { label: '统计', value: '统计', disabled: true },
  { label: '提示音', value: '提示音', disabled: true },
];
const warnConfig = [
  { label: '屏显', value: '屏显' },
  { label: '警报', value: '警报' },
  { label: '爆闪', value: '爆闪' },
  { label: '录像', value: '录像' },
  { label: '采集', value: '采集' },
  { label: '统计', value: '统计' },
];
Number(props.pageData.protobufVersion) >= 1 &&
  warnConfig.push({ label: '提示音', value: '提示音' });

const items = computed<ProFormProps['items']>(() => [
  itemRender('服务配置'),
  itemObj(
    '预警截屏服务',
    'radio',
    ['warnServerConfig', 'isOpenWarningScreenshot'],
    true,
    {
      options: radioOptions,
    },
  ),
  itemObj(
    '自动同步预警等级',
    'radio',
    ['warnServerConfig', 'isAutoSynWarnScope'],
    true,
    {
      options: radioOptions,
    },
  ),
  itemObj(
    '发送设备位置信息',
    'radio',
    ['warnServerConfig', 'isSendLocation'],
    true,
    {
      options: radioOptions,
    },
  ),
  itemObj('预警来源', 'select', ['warnServerConfig', 'warnSource'], true, {
    options: [
      { value: '0', label: '预警平台' },
      { value: '1', label: '管理平台' },
      { value: '2', label: '预警平台&管理平台' },
    ],
  }),
  itemRender('等级配置'),
  itemObj(...itemSelect('无预警烈度', 'warnNoneScope', false, 'grey')),
  itemObj(...itemSelect('蓝色预警烈度', 'warnBlueScope', true, '#409EFF')),
  itemObj(...itemSelect('黄色预警烈度', 'warnYellowScope', true, 'yellow')),
  itemObj(...itemSelect('橙色预警烈度', 'warnOrangeScope', true, 'orange')),
  itemObj(...itemSelect('红色预警烈度', 'warnRedScope', true, 'red')),
  itemRender('预警响应规则'),
  itemObj(
    ...itemNumber('正式预警震级', [
      'responseRuleConfig',
      'responseFormalMagnitude',
    ]),
  ),
  itemObj(
    ...itemNumber('演练预警震级', [
      'responseRuleConfig',
      'responseDrillMagnitude',
    ]),
  ),
  itemObj(
    ...itemNumber('测试预警震级', [
      'responseRuleConfig',
      'responseTestMagnitude',
    ]),
  ),
  itemObj(
    ...itemNumber('正式预警烈度', [
      'responseRuleConfig',
      'responseFormalIntensity',
    ]),
  ),
  itemObj(
    ...itemNumber('演练预警烈度', [
      'responseRuleConfig',
      'responseDrillIntensity',
    ]),
  ),
  itemObj(
    ...itemNumber('测试预警烈度', [
      'responseRuleConfig',
      'responseTestIntensity',
    ]),
  ),
  itemRender('响应动作配置'),
  itemObj(...itemCheckbox('无预警', 'warnNoneResponseConfig')),
  itemObj(...itemCheckbox('蓝色预警', 'warnBlueResponseConfig')),
  itemObj(...itemCheckbox('黄色预警', 'warnYellowResponseConfig')),
  itemObj(...itemCheckbox('橙色预警', 'warnOrangeResponseConfig')),
  itemObj(...itemCheckbox('红色预警', 'warnRedResponseConfig')),
  itemRender('参数配置'),
  itemObj(
    '播报倒计时',
    'input',
    ['responseParamsConfig', 'warnCountdownTime'],
    true,
    {
      addonAfter: '秒',
    },
  ),
  itemObj('地震S波速率', 'input', ['responseParamsConfig', 'waveSpeedS'], true),
  itemObj(
    '取消信息展示时间',
    'input',
    ['responseParamsConfig', 'warnCancelTime'],
    true,
    {
      addonAfter: '秒',
    },
  ),
  itemObj(
    '地震统计信息展示时间',
    'input',
    ['responseParamsConfig', 'warnInfoShowTime'],
    true,
    {
      addonAfter: '分',
    },
    { labelCol: { span: 11 } },
  ),
  itemObj(
    '地震到达后警报持续时间',
    'input',
    ['responseParamsConfig', 'warningTime'],
    true,
    {
      addonAfter: '秒',
    },
    { labelCol: { span: 12 } },
  ),
  itemObj(
    '盲区响应时间',
    'input',
    ['responseParamsConfig', 'blindResponseTime'],
    false,
    {
      addonAfter: '秒',
    },
  ),
  itemRender('响应模式'),
  itemObj(
    '预警响应模式',
    'select',
    ['responseModeConfig', 'warnShowModel'],
    true,
    {
      options: [
        { value: '0', label: '按最新预警更新' },
        { value: '1', label: '按本地预估烈度更新' },
        { value: '2', label: '按震级/震中更新' },
      ],
    },
  ),
  itemObj(
    '回复错误消息',
    'select',
    ['responseModeConfig', 'isResponseError'],
    true,
    {
      options: radioOptions,
    },
  ),
  itemObj(
    '响应测试消息',
    'select',
    ['responseModeConfig', 'isResponseTest'],
    true,
    {
      options: radioOptions,
    },
  ),
  {
    label: '响应开始-结束时间',
    type: 'input',
    field: 'warnTime',
    customRender(formState) {
      return (
        <TimeRangePicker
          v-model:value={formState.warnTime}
          format='HH:mm'
          valueFormat='HH:mm'
        />
      );
    },
    rules: [
      {
        required: true,
        type: 'array',
        message: '请选择响应开始-结束时间',
        trigger: 'blur',
      },
    ],
  },
  itemObj(
    '校验测试预警的UID/GRO',
    'select',
    ['responseModeConfig', 'isCheckTestUidGro'],
    true,
    {
      options: radioOptions,
    },
    { labelCol: { span: 12 } },
  ),
]);

const warnColorType = [
  'warnNoneResponseConfig',
  'warnBlueResponseConfig',
  'warnYellowResponseConfig',
  'warnOrangeResponseConfig',
  'warnRedResponseConfig',
];

const conversionFormat = () => {
  console.log(formState.value, 'formState.value');
  levelConfigList.forEach((key: any, index: any) => {
    const item = formState.value.warnLevelConfig[key];
    if (item) {
      formState.value[key] = item.split(',').map(Number);
    } else {
      formState.value[key] = [];
    }
  });

  warnColorType.forEach((key: any, index: any) => {
    const item = formState.value.responseActionConfig[key];
    const arr = item ? item.split(',') : [];
    const base = key == 'warnNoneResponseConfig' ? warnNoneConfig : warnConfig;
    formState.value[key] = arr.map((num: any, index: number) => {
      return num == 1 ? base[index].value : undefined;
    });
  });
  formState.value['warnTime'] = [
    formState.value.responseModeConfig.warnStartTime,
    formState.value.responseModeConfig.warnEndTime,
  ];
};
props.pageData.warnConfigsJson
  ? (() => {
      formState.value = JSON.parse(props.pageData.warnConfigsJson);
      conversionFormat();
      loaded.value = true;
    })()
  : getWarnConfig_2(props.pageData.code).then((res: any) => {
      formState.value = JSON.parse(res.data.paramsJson);
      formState.value.code = props.pageData.code;
      conversionFormat();
      loaded.value = true;
    });

const strAll = [...Array(12).keys()].map((i) => i + 1).join();
const formatReversal = (params: any) => {
  let levelConfigArr: any = [];
  levelConfigList.forEach((key: any, index: any) => {
    levelConfigArr = levelConfigArr.concat(params[key]);
    params['warnLevelConfig'][key] = params[key]?.join() || '';
  });
  if (levelConfigArr.join() != strAll) {
    message.warning('等级有缺漏，请检查选择等级');
    throw new Error('等级有缺漏，请检查选择等级');
  }

  warnColorType.forEach((key: any, index: any) => {
    const item = params[key];
    const base = key == 'warnNoneResponseConfig' ? warnNoneConfig : warnConfig;
    params['responseActionConfig'][key] = base
      .map((option: any) => {
        return item.includes(option.value) ? 1 : 0;
      })
      .join();
  });
  params.responseModeConfig.warnStartTime = params.warnTime[0];
  params.responseModeConfig.warnEndTime = params.warnTime[1];
  return {
    ...params,
    warnTime: undefined,
  };
};
const _updateWarnConfig = async (params: any) => {
  const submitObject = formatReversal(params);
  const code = props.pageData.code;
  const paramsJson = JSON.stringify(submitObject);
  await updateWarnConfig_2({ paramsJson, code });
};

const removeRepeat = (rawArr: any, removeArr: any) => {
  for (let i = rawArr.length - 1; i >= 0; i--) {
    if (removeArr.includes(rawArr[i])) {
      rawArr.splice(i, 1);
    }
  }
};

const onBeforeUpload: UploadProps['beforeUpload'] = (file) => {
  if (1024 * 1024 <= file.size / 1024) {
    message.warning('上传文件大小不能超过1G');
    return false;
  }
};
const customRequest: UploadProps['customRequest'] = ({
  file,
  filename,
  onError,
  onSuccess,
  onProgress,
}) => {
  const formData = new FormData();
  formData.append('file', file);
  importCertGen(formData, {
    skipError: true,
    onUploadProgress: onProgress,
  })
    .then((res) => {
      formRef.value.setFiledValue('publicKey', res.msg);
      onSuccess?.(res);
    })
    .catch((err) => {
      Modal.error({
        title: '提示',
        centered: true,
        content: err.message,
      });
      onError?.(err);
    });
};

defineExpose({
  async save() {
    const data = await formRef.value.validate();
    const submitObject = formatReversal(data);
    props.pageData.warnConfigsJson = JSON.stringify(submitObject);
  },
});
</script>
